﻿using IV.Components.Log.Enums;
using IV.Core;
using IV.Core.Data;
using IV.Core.Enums;
using IV.Core.Interfaces;
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Input;

namespace IV.Components.Log
{
    public class LogComponentViewModel : BindableBase
    {
        //最大长度
        private int _logMaxCount = 150;
        //log载入策略
        private ELogStrategy _eLogStrategy = ELogStrategy.AllLogFirst;

        //所有log，长度为_logMaxCount
        private ObservableCollection<LogItem> _logItems = new();
        //过滤后的log
        private ObservableCollection<LogItem> _filteredLogItems = new();

        /// <summary>
        /// 当前显示的Log
        /// 筛选项为ALL时使用_logItems，其他则使用_filteredLogItems
        /// </summary>
        public ObservableCollection<LogItem> ViewLogItems
        {
            get
            {
                if (ActiveLogLevel.Equals(ELogLevel.ALL))
                    return _logItems;
                else
                    return _filteredLogItems;
            }
            set
            {
                if (ActiveLogLevel.Equals(ELogLevel.ALL))
                    SetProperty(ref _logItems, value);
                else
                    SetProperty(ref _filteredLogItems, value);
            }
        }

        //筛选项，ALL不筛选
        private ELogLevel _activeLogLevel = ELogLevel.ALL;

        /// <summary>
        /// 等级筛选
        /// 非ALL时筛出有效log，并通知ui
        /// </summary>
        public ELogLevel ActiveLogLevel
        {
            get => _activeLogLevel;
            set
            {
                SetProperty(ref _activeLogLevel, value);
                if (!value.Equals(ELogLevel.ALL))
                    _filteredLogItems = new ObservableCollection<LogItem>(_logItems.Where(item => item.LogLevel.Equals(value)));
                RaisePropertyChanged(nameof(ViewLogItems));
            }
        }

        public ICommand EmptyListCommand { get; }
        public ICommand DownLoadCommand { get; }

        public LogComponentViewModel()
        {
            GetSetting();

            EmptyListCommand = new DelegateCommand(() =>
            {
                _logItems.Clear();
                _filteredLogItems.Clear();
                RaisePropertyChanged(nameof(ViewLogItems));
            });

            DownLoadCommand = new DelegateCommand(() =>
            {
                if (ViewLogItems.Count == 0)
                    return;
                var saveFileDialog = new SaveFileDialog
                {
                    Filter = "TXT File|*.txt",
                    Title = "Save to",
                    //给默认文件命名
                    FileName = DateTime.Now.ToString("yyyy-MM-dd_HHmmss")
                };
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string outDir = saveFileDialog.FileName;
                    var fStream = File.Create(outDir);
                    foreach (var item in ViewLogItems)
                    {
                        var logBytes = Encoding.Default.GetBytes($"{item}\r\n");
                        fStream.Write(logBytes, 0, logBytes.Length);
                    }
                    fStream.Flush();
                    fStream.Close();
                }
            });

            //接收log
            if (LogHelper.LogInstance != null)
                LogHelper.LogInstance.LogEvent += logItem =>
                {
                    System.Windows.Application.Current?.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        //总log长度超出移除最上面的一个，开启筛选时也以总log进行判断
                        if (_logItems.Count >= _logMaxCount)
                        {
                            RemoveLogitem();
                            //刷新筛选后的log
                            if (!_activeLogLevel.Equals(ELogLevel.ALL))
                                _filteredLogItems = new ObservableCollection<LogItem>(_logItems.Where(item => item.LogLevel.Equals(_activeLogLevel)));

                            RaisePropertyChanged(nameof(ViewLogItems));
                        }
                        //应收尽收,所有log加入到_logItems
                        if (_eLogStrategy.Equals(ELogStrategy.AllLogFirst) || _activeLogLevel.Equals(ELogLevel.ALL))
                        {
                            if (_activeLogLevel.Equals(ELogLevel.ALL))
                            {
                                ViewLogItems.Add(logItem);
                                return;
                            }
                            _logItems.Add(logItem);

                            if (logItem.LogLevel.Equals(_activeLogLevel))
                                ViewLogItems.Add(logItem);
                        }
                        //仅收筛选目标的log
                        else if (logItem.LogLevel.Equals(_activeLogLevel))
                        {
                            _logItems.Add(logItem);
                            ViewLogItems.Add(logItem);
                        }

                    }), null);
                };
        }

        private static readonly object _lockObj = new();
        private void RemoveLogitem()
        {
            lock (_lockObj)
            {
                _logItems.RemoveAt(0);
            }
        }

        private void GetSetting()
        {
            var setting = AppSettings.LocalSettings.GetScope("LogView");
            _logMaxCount = setting.Default("ViewLogMaxCount", 400).Value<int>("ViewLogMaxCount");
            _eLogStrategy = setting.Default("ViewLogStrategy", ELogStrategy.AllLogFirst).Value<ELogStrategy>("ViewLogStrategy");
            ActiveLogLevel = setting.Default("ViewLogLoglevel", ELogLevel.ERROR).Value<ELogLevel>("ViewLogLoglevel");
            AppSettings.LocalSettings.Save();
        }
    }
}
